package com.google.gwt.livinglife.client;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.http.client.URL;
import com.google.gwt.livinglife.client.LoginInfo;
import com.google.gwt.livinglife.client.LoginService;
import com.google.gwt.livinglife.client.LoginServiceAsync;
import com.google.gwt.livinglife.client.NotLoggedInException;
import com.google.gwt.livinglife.client.data.ChallengeData;
import com.google.gwt.livinglife.client.data.LivingLifeGroupData;
import com.google.gwt.livinglife.client.data.LivingLifeUserData;
import com.google.gwt.livinglife.client.widgets.ChallengeBox;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DeckPanel;
import com.google.gwt.user.client.ui.DecoratorPanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.InlineHTML;
/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class LivingLife implements EntryPoint, ValueChangeHandler<String>  {
	public static UserData userData = new UserData();
	private VerticalPanel mainPanel = new VerticalPanel();
	private TopBar topBar = new TopBar(userData);
	private DeckPanelWithSideLinks contents_panel = new DeckPanelWithSideLinks();
	private PublicHomePage publicHomePage = new PublicHomePage();
	private UserSettings userSettings = new UserSettings();
	private CreateGroup create_group_panel = new CreateGroup();
	private MyGroupsPanel my_groups_panel = new MyGroupsPanel();
	private GroupDataPanel group_data_panel = new GroupDataPanel();
	private ChallengeBox challenge_box = new ChallengeBox();
	// By default, no challenge link is added till someone tries to view a challenge.
	private Boolean is_challenge_box_added = false;
	public static  LoginInfo login_info;
	/**
	 * This is the entry point method.
	 */

	public void onModuleLoad() {
		// Check login status using login service.
		// Check login status using login service.
		LoginServiceAsync loginService = GWT.create(LoginService.class);
		loginService.login(GWT.getHostPageBaseURL(),
				new AsyncCallback<LoginInfo>() {
			public void onFailure(Throwable error) {
				handleError(error);
			}
			public void onSuccess(LoginInfo result) {
				userData.setLoginInfo(result);
				login_info = result;
				loadHomepage();
			}
		});
		
		String group_id_string = Window.Location.getParameter("group_id");
		String challenge_id_string = Window.Location.getParameter("challenge_id");
		String user_id_string = Window.Location.getParameter("user_id");
		if (group_id_string != null && !group_id_string.isEmpty()) {
			Long group_id = new Long(URL.decode(group_id_string));
			showGroupById(group_id);
		} else if (challenge_id_string != null && !challenge_id_string.isEmpty()) {
			Long challenge_id = new Long(URL.decode(challenge_id_string));
			showChallengeById(challenge_id);
		} else if (user_id_string != null && !user_id_string.isEmpty()) {
			String user_id = URL.decode(user_id_string);
			showUserById(user_id);
		}
		// Add history listener
		History.addValueChangeHandler(this);

		// Now that we've setup our listener, fire the initial history state.
		History.fireCurrentHistoryState();
	}
	
	private void loadHomepage() {
		topBar.assembleTopPanel(this);
		RootPanel.get("living life").add(mainPanel);
		mainPanel.add(topBar.getTopPanel());
		final InlineHTML line = new InlineHTML("<hr />");
		mainPanel.add(line);
		mainPanel.add(contents_panel.getMain_panel());
		contents_panel.addWidget(publicHomePage.getMainBody(), "Home", "Home");
		contents_panel.addWidget(userSettings.getMainPanel(), "Settings", "Settings");
		contents_panel.addWidget(create_group_panel.getMain_panel(), "CreateGroup", "CreateGroup");
		contents_panel.addWidget(my_groups_panel.getMain_panel(), "Groups", "Groups");
		contents_panel.addWidget(group_data_panel, "Find groups", "group_data");
		if (userData.getLoginInfo().isLoggedIn()) {
			userSettings.set_user_data(login_info.getUser_data());
			contents_panel.set_login_info(login_info);
			my_groups_panel.showGroups(login_info.getUser_data().getGroups());
		}
  	History.addValueChangeHandler(this);
  	contents_panel.showPanel(History.getToken());
	}
	
	private void handleError(Throwable error) {
		Window.alert(error.getMessage());
		if (error instanceof NotLoggedInException) {
			Window.Location.replace(userData.getLoginInfo().getLogoutUrl());
		}
	}
	
	public void showGroupById(Long id) {
		LivingLifeServiceAsync service = GWT.create(LivingLifeService.class);
		try {
			service.getGroupById(id, new AsyncCallback<LivingLifeGroupData>() {
				@Override
				public void onFailure(Throwable caught) {
					Window.alert("Invalid group Id was passed to the Url, might be an old Url");
				}
				@Override
				public void onSuccess(LivingLifeGroupData result) {
					contents_panel.showPanel("group_data");
					group_data_panel.showGroupData(result);
				}
			});
		} catch (ObjectNotFoundException e) {
			Window.alert("Invalid group Id was passed to the Url, might be an old Url");
		}
	}
	
	public void showChallengeById(Long challenge_id) {
		LivingLifeServiceAsync service = GWT.create(LivingLifeService.class);
		try {
			service.getChallengeById(challenge_id, new AsyncCallback<ChallengeData>() {

				@Override
				public void onFailure(Throwable caught) {
					Window.alert("Invalid group Id was passed to the Url, might be an old Url");
				}

				@Override
				public void onSuccess(ChallengeData result) {
					challenge_box.setChallenge_data(result);
					if (!is_challenge_box_added) {
						contents_panel.addWidget(challenge_box, "Challenge", "Challenge");
						is_challenge_box_added = true;
					}
					contents_panel.showPanel("Challenge");
				}
			});
		} catch (ObjectNotFoundException e) {
			Window.alert("Invalid group Id was passed to the Url, might be an old Url");
		}
	}
	
	private void showUserById(String userId) {
		LivingLifeServiceAsync service = GWT.create(LivingLifeService.class);
		try {
			service.getUserById(userId, new AsyncCallback<LivingLifeUserData>() {

				@Override
				public void onFailure(Throwable caught) {
					// TODO Auto-generated method stub
					
				}

				@Override
				public void onSuccess(LivingLifeUserData result) {
					// TODO Auto-generated method stub
					
				}
				
			});
		} catch (ObjectNotFoundException e) {
			Window.alert("Invalid group Id was passed to the Url, might be an old Url");
		}

	}

	public void onValueChange(ValueChangeEvent event) {
	}

	public static String getGroupIdUrl(Long group_id) {
		return GWT.getHostPageBaseURL() + "?group_id="  + group_id;
	}
	
	public static String getGroupNameUrl(String group_name) {
		return GWT.getHostPageBaseURL() + "?group_name="  + group_name;
	}

	public static LoginInfo getLogin_info() {
		return login_info;
	}
	public static String getUserIdUrl(String id) {
		return GWT.getHostPageBaseURL() + "?user_id="  + URL.encode(id);
	}
	public static String getChallengeIdUrl(Long id) {
		return GWT.getHostPageBaseURL() + "?challenge_id=" + id;
	}
}
